package com.xayy.health.core.utils;

import cn.kawins.base.utils.CollUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author dongxingli
 * createTime 2020/12/19
 * @version V1.0
 */
public class TreeUtil {
    /**
     * 将树结构集合转为没有树结构的List集合，并给标识层级号，从1开始
     *
     * @param treeList 树结构集合
     * @param <E>      数据类型
     * @return 没有树结构的List集合
     */
    public static <E extends TreeNode<E, ?>> List<E> toList(List<E> treeList) {
        if (treeList == null || treeList.isEmpty()) {
            return Collections.emptyList();
        }
        return treeToList(treeList, new ArrayList<>(0), 0);
    }

    /**
     * 获取树的叶子节点
     *
     * @param e   树结构
     * @param <E> 数据类型
     * @return 叶子节点集合
     */
    public static <E extends TreeNode<E, PK>, PK> List<E> leafNodeList(E e) {
        return leafNodeList(e, e.obtainId());
    }

    /**
     * 获取树上某个节点的叶子节点
     *
     * @param e   树结构
     * @param <E> 数据类型
     * @return 叶子节点集合
     */
    public static <E extends TreeNode<E, PK>, PK> List<E> leafNodeList(E e, PK pk) {
        if (e.obtainId().equals(pk)) {
            List<E> childList = e.getChildList();
            if (childList != null) {
                return addLeafNode(childList, new ArrayList<>());
            } else {
                return CollUtil.newArrayList(e);
            }
        } else {
            List<E> childList = e.getChildList();
            if (childList != null) {
                List<E> pkNodes = new ArrayList<>(0);
                findPkNode(pkNodes, childList, pk);
                if (!pkNodes.isEmpty()) {
                    if (pkNodes.get(0).getChildList() != null) {
                        return addLeafNode(pkNodes.get(0).getChildList(), new ArrayList<>());
                    } else {
                        return CollUtil.newArrayList(pkNodes.get(0));
                    }
                } else {
                    return CollUtil.emptyList();
                }
            } else {
                return CollUtil.emptyList();
            }
        }
    }

    private static <E extends TreeNode<E, PK>, PK> void findPkNode(List<E> pkNodes, List<E> treeList, PK pk) {
        for (E e : treeList) {
            if (e.obtainId().equals(pk)) {
                pkNodes.add(e);
            } else {
                List<E> childList = e.getChildList();
                if (childList != null) {
                    findPkNode(pkNodes, childList, pk);
                }
            }
        }
    }

    private static <E extends TreeNode<E, ?>> List<E> addLeafNode(List<E> treeList, List<E> list) {
        for (E e : treeList) {
            List<E> childList = e.getChildList();
            if (Objects.isNull(childList)) {
                list.add(e);
            } else {
                addLeafNode(childList, list);
            }
        }
        return list;
    }

    /**
     * 将树结构转为单List结构
     *
     * @param treeList
     * @param list
     * @param <E>
     * @return
     */
    @SuppressWarnings("unchecked")
    private static <E extends TreeNode<E, ?>> List<E> treeToList(List<E> treeList, List<E> list, int level) {
        level++;
        for (E x : treeList) {
            x.setNodeLevel(level);
            list.add(x);
            List<E> childList = x.getChildList();
            if (Objects.nonNull(childList)) {
                treeToList(childList, list, level);
            }
        }
        return list;
    }
}
